﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Threading;
using System.Diagnostics;

namespace BehaviorFramework
{
    public class ObservableProperty : INotifyPropertyChanged
    {
        private Dispatcher _uiDispatcher = Dispatcher.CurrentDispatcher;

        protected internal dynamic ViewModel { get; set; }

		public bool AreDependenciesMapped { get; set; }

		public bool IsCollectionType {get;set;}
		
		public Type BaseCollectionType { get; set; }

        public Type ParameterType { get; set; }

        public ObservableProperty(Func<dynamic> get, Action<dynamic> set = null, Type type= null)
        {
            if (type == null)
            {
                ParameterType = get.Invoke().GetType();
            }
            else
            {
                ParameterType = type;
            }

            Get = get;
            Set = set;
        }

        public string Name { get; set; }

        protected internal void InvokeSetter(dynamic value)
        {
            Set.Invoke(value);
            OnPropertyChanged(Name);
        }

        public Func<dynamic> Get
        {
            get;
            set;
        }

        public Action<dynamic> Set
        {
            get;
            set;
        }

        public List<ObservableProperty> DependsUpon = new List<ObservableProperty>();

        public event PropertyChangedEventHandler PropertyChanged;

        protected internal void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

        protected internal void OnPropertyChanged(ObservableProperty sender)
        {
            Debug.WriteLine("Property " + Name + " change raised by dependant property: " + sender.Name);
            OnPropertyChanged(Name);
        }
    }

}
